package com.DHH.Controller.Base;

import com.DHH.Annotation.SystemControllerLog;
import com.DHH.Config.Constant;
import com.DHH.Dto.FilterQuery;
import com.DHH.Entity.Base.BaseLoginRecord;
import com.DHH.Entity.Base.BaseRole;
import com.DHH.Mapper.Base.BaseRoleMapper;
import com.DHH.Mapper.Base.BaseUserMapper;
import com.DHH.Dto.Message;
import com.DHH.Dto.PageInfo;
import com.DHH.Dto.QueryInfo;
import com.DHH.Entity.Base.BaseUser;
import com.DHH.Service.Base.IBaseLoginRecordService;
import com.DHH.Service.Base.IBaseUserService;
import com.DHH.Util.MyUtil;
import com.DHH.Util.ReflectionUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import javax.servlet.http.HttpSession;


/**
 * Created by Administrator on 2017/4/15.
 */
@Controller
@RequestMapping("/Admin/Base/BaseUser")
public class BaseUserController {
    private Logger logger = LoggerFactory.getLogger(BaseUserController.class);
    @Autowired
    private BaseUserMapper baseUserMapper;
    @Autowired
    private IBaseUserService baseUserService;
    @Autowired
    private IBaseLoginRecordService baseLoginRecordService;
    @Autowired
    private BaseRoleMapper baseRoleMapper;

    @RequestMapping("/listPage")
    public String listPage(HttpSession session, ModelMap modelMap) {
        return "admin/baseUser/listBaseUserPage.jsp";
    }

    @RequestMapping("/addPage")
    public String addPage(HttpSession session, ModelMap modelMap) {
        List<BaseRole> baseRoleList = baseRoleMapper.selectAll();
        modelMap.put("roleList", baseRoleList);
        return "admin/baseUser/addBaseUserPage.jsp";
    }

    @RequestMapping("/updatePage")
    public String updatePage(HttpSession session, @RequestParam Integer id, ModelMap modelMap) {
        List<BaseRole> baseRoleList = baseRoleMapper.selectAll();
        BaseUser baseUser = baseUserMapper.getUserInfoByIdRelation(id);
        modelMap.put("baseUser", baseUser);
        System.out.println(baseUser);
        modelMap.put("roleList", baseRoleList);
        return "admin/baseUser/updateBaseUserPage.jsp";
    }
    @RequestMapping("/userCenter")
    public String updatePage(HttpSession session, ModelMap modelMap) {
        BaseUser baseUser= (BaseUser) session.getAttribute(Constant.USER_IDENTIFICATION);
        List<BaseRole> baseRoleList = baseRoleMapper.selectAll();
         baseUser = baseUserMapper.getUserInfoByIdRelation(baseUser.getId());
        modelMap.put("baseUser", baseUser);
        System.out.println(baseUser);
        modelMap.put("roleList", baseRoleList);
        return "admin/baseUser/userCenter.jsp";
    }
    @RequestMapping("/modifyPassowrdPage")
    public String modifyPassowrdPage(HttpSession session) {

        return "admin/baseUser/modifyPassword.jsp";
    }
    @RequestMapping("/modifyPassowrd")
    @ResponseBody
    public Message modifyPassoword(HttpSession session,@RequestParam String oldPassword,@RequestParam String newPassword,@RequestParam String newPasswordConfirm) {
       BaseUser baseUser= (BaseUser) session.getAttribute(Constant.USER_IDENTIFICATION);
        Message msg=new Message();
        try {
            if(newPassword.length()<6||newPassword.length()>16)
            {
                msg.setMsg("新密码长度错误");
                return msg;
            }
            if (!newPassword.equals(newPasswordConfirm))
            {
                msg.setMsg("两次密码不一致");
                return msg;
            }
            if (!newPassword.equals(newPasswordConfirm))
            {
                msg.setMsg("两次密码不一致");
                return msg;
            }
            String password= MyUtil.createMD5(oldPassword);//对密码进行第一次加密
             oldPassword  =MyUtil.createMD5(password+baseUser.getSalt());
             if(!oldPassword.equals(baseUser.getToken()))
             {
                 msg.setMsg("旧密码错误");
                 return msg;
             }
             password= MyUtil.createMD5(newPassword);//对密码进行第一次加密
            newPassword  =MyUtil.createMD5(password+baseUser.getSalt());
            BaseUser user=new BaseUser();
            user.setId(baseUser.getId());
            user.setToken(newPassword);
            baseUserService.updateBaseUser(user);
            msg.setMsg("修改密码成功");
            msg.setState(true);
            return msg;
        }catch (Exception e)
        {
            e.printStackTrace();
            msg.setMsg("操作失败，请稍后重试");
            return msg;
        }

    }
    @RequestMapping("/detailsPage")
    public String detailPage(HttpSession session, @RequestParam Integer id, ModelMap modelMap) {
        return "admin/baseUser/detailsBaseUserPage.jsp";
    }

    @RequestMapping("/add")
    @ResponseBody
    public Message add(@Valid BaseUser baseUser, BindingResult result, @RequestParam(value = "roleId[]", required = true) Integer[] roleIdArray) {
        Message msg = new Message();
        if (result.hasErrors()) {
            List<FieldError> err = result.getFieldErrors();
            for (FieldError fe : err) {
                msg.addError(fe.getField().toString(), fe.getDefaultMessage());
            }
            return msg;
        }
        try {
            List<BaseRole> roleList = new ArrayList<BaseRole>();
            for (Integer i :
                    roleIdArray) {
                BaseRole baseRole = new BaseRole();
                baseRole.setId(i);
                roleList.add(baseRole);
            }
            baseUser = baseUserService.insertBaseUserAdmin(baseUser, roleList);
            msg.setMsg("添加用户成功!");
            msg.setData(baseUser);
            msg.setState(true);
            return msg;
        } catch (Exception e) {
            msg.setMsg("操作失败!");
            return msg;
        }
    }

    @RequestMapping("/saveOrUpdate")
    @ResponseBody
    public Message saveOrUpdate(BaseUser baseUser, BindingResult result, @RequestParam(value = "roleId[]", required = true) Integer[] roleIdArray) {
        Message msg = new Message();
        if (result.hasErrors()) {
            List<FieldError> err = result.getFieldErrors();
            for (FieldError fe : err) {
                msg.addError(fe.getField().toString(), fe.getDefaultMessage());
            }
            return msg;
        }
        try {
            List<BaseRole> roleList = new ArrayList<BaseRole>();
            for (Integer i : roleIdArray) {
                BaseRole baseRole = new BaseRole();
                baseRole.setId(i);
                roleList.add(baseRole);
            }
            baseUser = baseUserService.saveOrUpdateBaseUser(baseUser,roleList);
            msg.setMsg("操作成功!");
            msg.setData(baseUser);
            msg.setState(true);
            return msg;
        } catch (Exception e) {
            e.printStackTrace();
            msg.setMsg("操作失败，请稍后重试!");
            return msg;
        }
    }

    @RequestMapping("/delete")
    @ResponseBody
    public Message delete(@RequestParam Integer id) {
        Message msg = new Message();
        try {
            BaseUser baseUser = new BaseUser();
            baseUser.setId(id);
            baseUser = baseUserService.deleteBaseUser(baseUser);
            msg.setMsg("操作成功");
            msg.setState(true);
            msg.setData(baseUser);
            return msg;
        } catch (Exception e) {
            msg.setMsg("操作失败");
            return msg;
        }
    }

    @RequestMapping("/update")
    @ResponseBody
    public Message update(BaseUser baseUser) {
        Message msg = new Message();
        try {
            baseUserService.updateBaseUser(baseUser);
            msg.setData(baseUserMapper.selectBaseUserById(baseUser));
            msg.setMsg("操作成功！");
            msg.setState(true);
            return msg;
        } catch (Exception e) {
            msg.setMsg("操作失败，请稍后重试");
            return msg;
        }
    }

    @ResponseBody
    @RequestMapping("/query")
    public PageInfo<BaseUser> query(QueryInfo queryInfo) {
        System.err.println("--------------查询参数---------------");
        System.err.println(queryInfo);
        System.err.println("--------------查询参数---------------");
        PageHelper.startPage(queryInfo.getCurrentPage(), queryInfo.getPageSize());
        PageHelper.orderBy(queryInfo.getSort() + " " + queryInfo.getOrder());
        if (queryInfo.getType() == null) {
            queryInfo.setType("search");
        }
        try {
            if (queryInfo.getType().equals("screen")) {
                return this.screen(queryInfo);
            }
            if (queryInfo.getType().equals("filter")) {

                return this.searchFilter(queryInfo);
            }
            return this.search(queryInfo);
        } catch (Exception e) {
            e.printStackTrace();
            PageInfo<BaseUser> p = new PageInfo<BaseUser>();
            p.setMsg("查询失败，请稍后重试！");
            return p;
        }

    }


    /**
     * 查询
     *
     * @param queryInfo
     * @return
     */
    private PageInfo<BaseUser> search(QueryInfo queryInfo) {
        System.out.println("---------\n" + queryInfo);

        BaseUser baseUser = new BaseUser();
        if (queryInfo.getSearchKey() != null&&!queryInfo.getSearchKey().equals("")) {
            baseUser.setIdentity(  queryInfo.getSearchKey() + "%");
            baseUser.setPhone( queryInfo.getSearchKey() + "%");
            baseUser.setUsername(queryInfo.getSearchKey() + "%");
        }
        PageInfo<BaseUser> pageInfo = new PageInfo<BaseUser>();
        Page<BaseUser> page = (Page<BaseUser>) baseUserMapper.searchByBaseUser(baseUser);
        pageInfo.setRows(page.getResult());
        pageInfo.setTotalRow(page.getTotal());
        pageInfo.setCurrentPage(queryInfo.getCurrentPage());
        return pageInfo;
    }

    /**
     * 筛选
     *
     * @param queryInfo
     * @return
     */
    private PageInfo<BaseUser> screen(QueryInfo queryInfo) {
        PageInfo<BaseUser> pageInfo = new PageInfo<BaseUser>();
        BaseUser baseUser = new BaseUser();
        for (String key : queryInfo.getMap().keySet()) {
            ReflectionUtils.setFieldValue(baseUser, key, queryInfo.getMap().get(key));
        }
        Page<BaseUser> page = (Page<BaseUser>) baseUserMapper.screenByBaseUser(baseUser);
        pageInfo.setRows(page.getResult());
        pageInfo.setTotalRow(page.getTotal());
        pageInfo.setCurrentPage(queryInfo.getCurrentPage());
        return pageInfo;
    }

    /**
     * 过滤
     *
     * @param queryInfo
     * @return
     */
    private PageInfo<BaseUser> searchFilter(QueryInfo queryInfo) throws ParseException {
        BaseUser baseUser = new BaseUser();
        PageInfo<BaseUser> pageInfo = new PageInfo<BaseUser>();
        FilterQuery filterQuery = new FilterQuery();
        filterQuery.setStartValue(queryInfo.getFilterStartValue());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        filterQuery.setEndValue(sdf.format(new Date(sdf.parse(queryInfo.getFilterEndValue()).getTime() + 24 * 3600 * 1000)));
        Page<BaseUser> page = (Page<BaseUser>) baseUserMapper.filterByBaseUser(filterQuery);
        pageInfo.setRows(page.getResult());
        pageInfo.setTotalRow(page.getTotal());
        pageInfo.setCurrentPage(queryInfo.getCurrentPage());
        return pageInfo;
    }

    /**
     * 用户登录操作
     *
     * @param user         身份和令牌
     * @param identifyCode //验证码
     * @param autoLogin    //是否自动登录
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/userLogin")
    @SystemControllerLog(description = "后台管理系统登录")
    public Message userLogin(BaseUser user, String identifyCode, Integer autoLogin, HttpServletRequest request, HttpServletResponse response) {
        BaseLoginRecord baseLoginRecord = new BaseLoginRecord();
        baseLoginRecord.setLoginName(user.getIdentity());
        baseLoginRecord.setLoginIp(MyUtil.getRemoteHost(request));
        baseLoginRecord.setLoginTime(new Date());
        baseLoginRecord.setIsSuccess(0);
        baseLoginRecord.setTypeId(1);
        identifyCode = identifyCode.toLowerCase();
        Message msg = new Message();
        org.apache.shiro.subject.Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        String sessionIdentifyCode = (String) session.getAttribute(Constant.IDENTIFY_CODE_MARK);
        session.setAttribute(Constant.IDENTIFY_CODE_MARK, null);
        if (identifyCode == null || !identifyCode.equals(sessionIdentifyCode)) {
            msg.setMsg("验证码错误，请输入正确的验证码!");
            return msg;
        }
        if (user.getIdentity() == null || user.getIdentity().equals("")) {
            msg.setMsg("请输入正确的用户名!");
            return msg;
        }
        if (user.getToken() == null || user.getToken().equals("")) {
            msg.setMsg("请输入正确的密码!");
            return msg;
        }
        Integer number = (Integer) session.getAttribute(Constant.LOGIN_FAILED_NUMBER_MARK);
        number = (number == null ? 0 : number);
        if (number >= Constant.LOGINFAILEDNUMBER) {
            msg.setMsg("您重复登录次数过多，请30分钟后重试！");
            baseLoginRecord.setLoginMessage("登录次数过多..");
            baseLoginRecord.setIsSuccess(0);
            baseLoginRecordService.insertBaseLoginRecord(baseLoginRecord);
            return msg;
        }
        try {
            BaseUser u = new BaseUser();
            u.setIdentity(user.getIdentity());
            u.setIslock(0);
            u = baseUserMapper.selectOne(u);
            String password = MyUtil.createMD5(user.getToken());
            password = MyUtil.createMD5(password + u.getSalt());
            UsernamePasswordToken token = new UsernamePasswordToken(user.getIdentity(), password);

            if (autoLogin != null && autoLogin == 1) {
                token.setRememberMe(true);
            }
            currentUser.login(token);
            BaseUser user1=new BaseUser();
            user1.setId(u.getId());
            user1.setIsOnline(1);
            baseUserService.updateBaseUser(user1);
            u = baseUserMapper.getUserInfoByIdRelation(u.getId());
            List<BaseRole> baseRoleList=baseRoleMapper.selectSysRoleByUserId(u.getId());
            u.setBaseRoleSet(new HashSet<BaseRole>());
            for (BaseRole b:
                    baseRoleList) {
                u.getBaseRoleSet().add(b);
            }
            System.out.println("实体类：" + u);
            session.setAttribute(Constant.USER_IDENTIFICATION, u);
            msg.setState(true);
            msg.setMsg("恭喜你登录成功");
            baseLoginRecord.setLoginMessage("登录成功");
            baseLoginRecord.setUserId(u.getId());
            baseLoginRecord.setIsSuccess(1);
            baseLoginRecordService.insertBaseLoginRecord(baseLoginRecord);
            return msg;

        } catch (Exception e) {
            e.printStackTrace();
            Integer loginfailedNumber = (Integer) session.getAttribute(Constant.LOGIN_FAILED_NUMBER_MARK);
            if (loginfailedNumber == null) {
                loginfailedNumber = 0;
            }
            msg.setMsg("登录失败，请检查账号或密码错误！");
            baseLoginRecord.setLoginMessage("登录失败，账号或者密码错误..");
            baseLoginRecordService.insertBaseLoginRecord(baseLoginRecord);
            session.setAttribute(Constant.LOGIN_FAILED_NUMBER_MARK, loginfailedNumber + 1);
            return msg;
        }

    }
}

